package internal

import (
	"encoding/json"
	"strings"
	"time"

	"gitee.com/JMArch/service_addr_syncer/pkg/doveclient"
	"github.com/zeast/logs"
)

type DoveClientConf struct {
	Env      string
	Username string
	Secret   string
	MapKey   string
	Callback func(map[string]string)
}

type DoveClient struct {
	conf DoveClientConf
	cli  *doveclient.Client
}

func NewDoveClient(conf DoveClientConf) (*DoveClient, error) {
	cli, err := doveclient.NewClient(conf.Username, conf.Secret, conf.Env)
	if err != nil {
		return nil, err
	}

	return &DoveClient{
		conf: conf,
		cli:  cli,
	}, nil
}

func (dc *DoveClient) Watch() error {
	w, err := doveclient.NewWatcher(dc.cli, dc.conf.MapKey, time.Second*10)
	if err != nil {
		return err
	}

	go func() {

		ch := w.Start()

		for resp := range ch {
			if resp.Err != nil {
				logs.Error(resp.Err)
			} else {
				var m = make(map[string]map[string]string)
				err = json.Unmarshal(resp.Content, &m)
				if err != nil {
					logs.Fatalf("get serviceName2DoveKey %s, content:%v", err, resp.Content)
				}

				if dc.conf.Callback != nil {
					dc.conf.Callback(m["ServiceName2DoveKey"])
				}
			}
		}
	}()

	return nil
}

func (dc *DoveClient) WatchKey(key string, handler func(value interface{})) error {
	w, err := doveclient.NewWatcher(dc.cli, key, time.Second*10)
	if err != nil {
		return err
	}
	splitKeys := strings.Split(key, ".")
	mapKey := splitKeys[len(splitKeys)-1]
	go func() {

		ch := w.Start()

		for resp := range ch {
			if resp.Err != nil {
				logs.Error(resp.Err)
			} else {
				var m = make(map[string]interface{})
				err = json.Unmarshal(resp.Content, &m)
				if err != nil {
					logs.Errorf("watch dove key %s: %s", key, err.Error())
					continue
				}
				handler(m[mapKey])
			}
		}
	}()

	return nil
}

func (dc *DoveClient) UpdateDoveKey(cnfName string, content []byte) error {
	return dc.cli.UpdateDoveKey(cnfName, content)
}

func (dc *DoveClient) PublishDoveKey(cnfName string) error {
	return dc.cli.PublishDoveKey(cnfName)
}
